package org.waddy.framework.app.web.filter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.Filter;


import org.waddy.framework.app.web.entity.UserContext;
import org.waddy.framework.app.web.system.SysUserSVO;
import org.waddy.framework.pub.util.common.StringUtil;



/**
 * @Title 安全认证过滤器
 * @version 1.0
 * @author zhangdapeng
 * @Created 2012-7-10
 * Copyright (c) 2012 PanGene InfoAnalytics.
 *
 * @Description 判断用户是否登录，session是否失效，及失效后跳转等<br>
 * 		需配置初始参数，指定应用路径及session失效后跳转页面<br>
 * 		注意：主应用和子应用配置不同<br>
 */
public class AuthFilter implements Filter   {

    private FilterConfig config;
    private String currentContextPath;
    private String root_page;
    private String login_page;
    private boolean isMaster=true;//false-为插件应用，true-为门户主应用
    
    public void destroy() {
       config = null;
    }
    
    public void init(FilterConfig filterconfig) throws ServletException {
        // 从部署描述符中获取登录页面和首页的URI，用于session失效时跳转到登录页面
        config = filterconfig;
        currentContextPath = filterconfig.getServletContext().getContextPath();
        root_page = filterconfig.getInitParameter("rootPage");
        login_page = filterconfig.getInitParameter("loginPage");
//        System.out.println("root_page==="+root_page);
//        System.out.println("login_page==="+login_page);
//        if("/".equals(root_page)){
//        	isMaster = true;
//        	root_page = currentContextPath;
//        	System.out.println("Portal主应用启动 - "+currentContextPath);
//        }else{
//        	isMaster = false;
//        	System.out.println("Portal从应用启动 - "+currentContextPath);
//        }
//        if(null == login_page) {
//            throw new ServletException("没有找到登录页面");
//        }
    }
    
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse rsp = (HttpServletResponse) response;
        HttpSession session = req.getSession();
        //response.setCharacterEncoding("utf-8");
        System.out.println(">>>>>>>>>>>>sessionId:"+session.getId());
        
//        /** portal共享seesion判断处理逻辑
//         *  此处需配合PortalListener协同完成。 
//         **/
//        String portalContextPath = root_page;
//        System.out.println("["+session.getServletContext().getContextPath()+"]获取portalContextPath："+portalContextPath);
//        ServletContext portalContext = session.getServletContext().getContext(portalContextPath);
//        if(isMaster){
//        	//如果当前应用为portal主应用，那么为用户缓存全局session
//        	System.out.println("["+currentContextPath+"]"+"缓存portalSession：当前应用为portal主应用");
//        	portalContext.setAttribute("portalSession", session);
//        }else{
//        	//否则为portal插件应用，改用portalSession进行权限判断
//        	System.out.println("["+currentContextPath+"]"+"获取portalSession：当前应用为portal插件应用");
//        	session = (HttpSession) portalContext.getAttribute("portalSession");
//        	//取master应用的用户信息，拷贝到slave应用的session中，这样slave应用本身就可以获取到用户自身相关的缓存信息了
//        	UserContext userContext = (UserContext)session.getAttribute(UserContext.USER_CONTEXT_KEY);
//        	if(userContext!=null){
//        		SysUserSVO user = userContext.getSysUser();
//        		System.out.println("当前登录用户："+user);
//        	}
//        	req.getSession().setAttribute(UserContext.USER_CONTEXT_KEY, userContext);
//        }
        
        String request_uri = req.getRequestURI().toUpperCase();    //得到用户请求的URI
        String ctxPath = req.getContextPath();    //得到web应用程序的上下文路径
        String uri = request_uri.substring(ctxPath.length());    //去除上下文路径，得到剩余部分的路�?   
        try {
//        	//UserContext userContext = (UserContext) session.getAttribute(UserContext.USER_CONTEXT_KEY);//此处会报ClassCastException
//        	/**
//        	 * 【session对象序列化与反序列化】begin...
//        	 * */
//        	Object userContextObj = session.getAttribute(UserContext.USER_CONTEXT_KEY);
//        	ByteArrayOutputStream byteOut = new ByteArrayOutputStream();  
//        	ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
//        	objOut.writeObject(userContextObj);
//        	objOut.flush();
//        	ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(byteOut.toByteArray()));
//        	UserContext userContext = (UserContext) in.readObject();
//        	/**
//        	 * 【session对象序列化与反序列化】end...
//        	 * */
        	Object userContextObj = session.getAttribute(UserContext.USER_CONTEXT_KEY);
            if(request_uri.indexOf("LOGIN.JSP") == -1 && request_uri.indexOf("LOGIN.DO")==-1 && request_uri.indexOf("LOGINACTION")==-1 && userContextObj == null) {
            	//begin.判断是否为匿名访问公共门户页面
            	String requestFuncNode = req.getParameter("navFuncId");
            	if("99999999".equals(requestFuncNode)){
            		chain.doFilter(request, response);
            		return;
            	}
            	//end.
            	rsp.setCharacterEncoding("utf-8");
            	String targetLocation = root_page + login_page;
                //rsp.sendRedirect(targetLocation);
                PrintWriter out = rsp.getWriter();
                //out.println("<script type='text/javascript'>window.top.location='"+targetLocation+"'</script>");
                out.print("<script>alert('您的会话已失效，请重新登录 ^_^');window.top.location='"+targetLocation+"'</script>");
                //RequestDispatcher dispatcher = request.getRequestDispatcher(login_page);
                //dispatcher.forward(req, rsp); 
                return;
            }
            else {
                chain.doFilter(request, response);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ServletException e1) {
            e1.printStackTrace();
        }
    }

}
